package com.zjinyin.forum.service.impl;

import com.zjinyin.forum.common.AppResult;
import com.zjinyin.forum.common.ResultCode;
import com.zjinyin.forum.dao.MessageMapper;
import com.zjinyin.forum.exception.ApplicationException;
import com.zjinyin.forum.model.Message;
import com.zjinyin.forum.model.User;
import com.zjinyin.forum.service.IMessageService;
import com.zjinyin.forum.service.IUserService;
import com.zjinyin.forum.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: DELL
 * Date: 2023-08-13
 * Time: 15:26
 */


@Slf4j
@Service
public class MessageExtService implements IMessageService {

    @Resource
    private MessageMapper messageMapper;

    @Resource
    private IUserService userService;

    /**
     * @param message 信息对象
     */
    @Override
    public void create(Message message) {
        // 1. 参数校验
        if (message == null || message.getPostUserId() <= 0 || message.getReceiveUserId() == null || message.getReceiveUserId() <= 0
                || StringUtil.isEmpty(message.getContent())) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        // 2. 检验接受者是否存在
        User user = userService.selectByPrimaryKey(message.getReceiveUserId());
        if (user == null || user.getDeleteState() == 1) {
            log.warn("userId : " + message.getPostUserId() + " " + ResultCode.FAILED_USER_NOT_EXISTS);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        // 3. 设置默认值
        // 设置状态 - 0 未读 1 已读 默认为 0
        message.setState((byte) 0);
        // 设置删除状态
        message.setDeleteState((byte) 0);
        // 设置创建更新时间
        Date date = new Date();
        message.setCreateTime(date);
        message.setUpdateTime(date);

        // 4. 创建 message
        int row = messageMapper.insertSelective(message);

        if (row != 1) {
            log.warn(ResultCode.FAILED + " , 受影响行数不为 1 错误");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED) + " , 受影响行数不为 1 错误");
        }

        // 5. 打印日志
        log.info("新增消息回复成功!");

    }


    /**
     * 根据接收者 id 查询其未读站内信数量
     *
     * @param receiveUserId 接收者 id
     * @return 返回站内信未读数量
     */
    @Override
    public Integer selectUnReadMessage(Long receiveUserId) {
        // 1. 参数校验
        if (receiveUserId == null || receiveUserId <= 0) {
            log.warn("接收者 receiveUserId : " + receiveUserId + " " + ResultCode.FAILED_PARAMS_VALIDATE);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        Integer count = messageMapper.selectUnReadMessage(receiveUserId);

        // 正常查询结果只会 >= 0
        if (count == null) {
            log.warn(ResultCode.ERROR_SERVICES.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }
        log.info("当前用户站内信查未读数查询成功");
        return count;
    }


    /**
     * 根据接收者 id 查询其站内信所有对象
     *
     * @param receiveUserId 接收者 id
     * @return 站内信对象
     */
    @Override
    public List<Message> selectByReceiveUserId(Long receiveUserId) {

        // 1. 参数校验
        if (receiveUserId == null || receiveUserId <= 0) {
            log.warn("接收者 receiveUserId : " + receiveUserId + " " + ResultCode.FAILED_PARAMS_VALIDATE);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        // 2. 调用查询
        List<Message> list = messageMapper.selectByReceiveUserId(receiveUserId);

        if (list == null) {
            list = new ArrayList<>();
        }

        return list;
    }


    /**
     * 根据制定 id 查询站内信, 并更新其状态
     *
     * @param id    站内信 id
     * @param state 指定 id 站内信的状态
     */
    @Override
    public void updateStateById(Long id, Byte state) {
        // 1. 参数检验
        if (id == null || id <= 0 || state < 0 || state > 2) {
            log.warn("站内信 id : " + " " + ResultCode.FAILED_PARAMS_VALIDATE);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        // 2. 根据 id 查询站内信是否存在
        Message message = messageMapper.selectByPrimaryKey(id);
        if (message == null || message.getDeleteState() == 1) {
            log.warn("站内信 id : " + " " + ResultCode.Message_NOT_EXISTS);
            throw new ApplicationException(AppResult.failed(ResultCode.Message_NOT_EXISTS));
        }

        // 3. 创建更新对象
        Message updateMessage = new Message();
        updateMessage.setId(id);
        updateMessage.setState(state);
        updateMessage.setUpdateTime(new Date());

        // 4. 写入数据库
        int row = messageMapper.updateByPrimaryKeySelective(updateMessage);

        if (row != 1) {
            log.warn(ResultCode.FAILED + " , 受影响行数不为 1 错误");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED) + " , 受影响行数不为 1 错误");
        }

        log.info("站内信 id " + id + " 状态更新成功");
    }


    /**
     * 查询指定 id 的站内信
     *
     * @param id 站内信 id
     */
    @Override
    public Message selectById(Long id) {

        // 1. 参数检验
        if (id == null || id <= 0) {
            log.warn("站内信 id : " + " " + ResultCode.FAILED_PARAMS_VALIDATE);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        // 2. 根据 id 查询站内信是否存在
        Message message = messageMapper.selectByPrimaryKey(id);
        if (message == null || message.getDeleteState() == 1) {
            log.warn("站内信 id : " + " " + ResultCode.Message_NOT_EXISTS);
            throw new ApplicationException(AppResult.failed(ResultCode.Message_NOT_EXISTS));
        }

        return message;
    }


    @Override
    @Transactional
    public void replyMessage(Long repliedId, Message message) {
        // 1. 参数校验
        if (repliedId == null || repliedId <= 0) {
            log.warn("站内信 id : " + " " + ResultCode.FAILED_PARAMS_VALIDATE);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        // 2. 根据 repliedId 查询站内信信息
        Message existsMessage =messageMapper.selectByPrimaryKey(repliedId);

        if(existsMessage == null || existsMessage.getDeleteState() == 1) {
            log.warn("repliedId : " + repliedId + " " + ResultCode.Message_NOT_EXISTS);
            throw new ApplicationException(AppResult.failed(ResultCode.Message_NOT_EXISTS));
        }

        // 将已回复的站内信更新为 - 已回复状态
        updateStateById(repliedId, (byte)2);

        log.info("repliedId : " + repliedId + " 回复站内信状态更新成功 ");

        // 将当前登陆者回复的 message 对象写回到数据库
        create(message);
        log.info("发送者 id : " + existsMessage.getReceiveUserId() + " 给接收者 id : " + existsMessage.getPostUserId() + " 回复消息成功");
    }
}
